# -*- coding: utf-8 -*-
# copyright (c) 2007
# Kazumasa Suzuki
from zope.interface import implements
from twisted.internet import reactor, protocol
from twisted.protocols import basic
import os, sys
# midtown stuff
#from midtown.mtaxiom import *
#from midtown import mtaxiom
#import midtown.mtaxiom
from mtaxiom import *

class ChatProtocol(basic.LineReceiver):
    def __init__(self):
        self.mode = 'COMMAND'
        self._from = None
        self._to = None
        self.__msg = {}
        
    def lineReceived(self, line):
        return getattr(self, 'state_' + self.mode)(line)

    def state_COMMAND(self, line):
        line = line.strip()
        parts = line.split(None, 1)
        if parts:
            method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
            if len(parts) == 2:
                method(parts[1])
            else:
                method('')
        else:
            self.sendSyntaxError()

    def sendSyntaxError(self):
        self.sendLine('Syntax Error')

    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.upper(), None)

    def do_UNKNOWN(self, rest):
        self.sendLine('Unkown command')

    def do_QUIT(self, rest):
        self.transport.loseConnection()
    
    def do_FROM(self, rest):
        # never set from twice
        if self._from:
            self.sendSyntaxError()
        self._to = '' # clear old data
        self._from = rest
        self.sendLine('ok get from')

    def do_TO(self, rest):
        if self._to:
            self.sendSyntaxError()
        self._to = rest
        self.sendLine('ok get to')

    def do_DATA(self, rest):
        if self._from is None or (self._to is None):
            self.sendSyntaxError()
            return
        self.mode = 'DATA'
        self.__msg = {'From':self._from, 'To':self._to, 'Body':[]}
        self._from = None
        self._to = None

    def dataLineReceived(self, line):
        if line[:1] == '.':
            if line == '.':
                self.sendLine('ok data')
                self.mode = 'COMMAND'
                return
            line = line[1:]

        self.__msg['Body'].append(line)
        #self.lineReceived(line)
        self.broadcast(line, self._from, self._to)

    state_DATA = dataLineReceived

    def broadcast(self, line, who, room):
        print 'broadcast'



class ChatServerFactory(protocol.ServerFactory):
    protocol = ChatProtocol


class ChatRoom(object):

    def __init__(self, name=u'WebChat'):
        self.chatters = []
        self.store = MidtownManager().store
        self.room = MtRoom(name = name,
                           roomObject = self,
                           store = self.store)
        self.roomname = name

    def wall(self, message):
        for chatter in self.chatters:
            chatter.wall(message)

    def tellEverybody(self, who, what):
        MtMessage(who=unicode(who.username), 
                  subject=u'From Web',
                  body = unicode(what),
                  room = self.room,
                  roomname = self.roomname,
                  store = self.store)
        for chatter in self.chatters:
            chatter.hear(who.username, what)

    def makeChatter(self, chatter):
        self.chatters.append(chatter)
        return cb

if __name__ == "__main__":
    port = 5001
    reactor.listenTCP(port, ChatServerFactory())
    reactor.run()
